﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Marbles.Core.Connectors;
using System.Web;

namespace Marbles.Core.BBS
{
    public class ForumPost
    {
        public Int64 PostId { get { return _postid; } }
        public Int64 ParentPostId { get { return _parentpostid; } }
        public string SiteId { get { return _siteid; } }
        public string ForumName { get { return _forumname; } }
        public string Title { get { return _title; } set { _title = value; } }
        public string Body { get { return _body; } set { _body = value; } }
        public string Author { get { return _postby; } set { _postby = value; } }
        public DateTime PostDate { get { return _postdate; } set { _postdate = value; } }
        public string PostDateString { get { return (PostDate.Year <= 1980) ? "" : PostDate.ToString("ddd") + " " + PostDate.ToShortDateString() + " " + PostDate.ToShortTimeString(); } }
        public bool Approved { get { return _approved; } }
        public bool Locked { get { return _locked; } set { _locked = value; } }
        public bool Sticky { get { return _sticky; } set { _sticky = value; } }
        public Int32 Replies { get { return _replies; } }
        public DateTime LastPostDate { get { return _lastpostdate; } }
        public string LastPostDateString { get { return (LastPostDate.Year <= 1980) ? PostDateString : LastPostDate.ToString("ddd") + " " + LastPostDate.ToShortDateString() + " " + LastPostDate.ToShortTimeString(); } }
        public Int32 LikeCount { get { return _likecount; } }

        private Int32 _likecount = 0;
        private DateTime _lastpostdate = DateTime.MinValue;
        private bool _sticky = false;
        private bool _locked = false;
        private string _siteid;
        private string _forumname;
        private string _title;
        private string _body;
        private string _postby;
        private DateTime _postdate = DateTime.MinValue;
        private bool _approved;
        private Int64 _postid;
        private Int64 _parentpostid;
        private Int32 _replies;

        public ForumPost(string siteid, string forumname, Int64 postid)
            : this()
        {
            DataConnection dbc = new DataConnection();
            Command cmd = new Command("SELECT * FROM forumitems WHERE siteid = @siteid AND forumname = @forumname AND postid = @postid");
            cmd.AddParameter("@siteid", siteid);
            cmd.AddParameter("@forumname", forumname);
            cmd.AddParameter("@postid", postid);

            DataTable dt = dbc.FetchDataTable(cmd);
            if (dt.Rows.Count > 0)
            {
                _likecount = Convert.ToInt32(dt.Rows[0]["likecount"]);
                _replies = Convert.ToInt32(dt.Rows[0]["replies"]);
                _sticky = Convert.ToBoolean(dt.Rows[0]["sticky"]);
                _locked = Convert.ToBoolean(dt.Rows[0]["locked"]);
                _siteid = dt.Rows[0]["siteid"].ToString();
                _forumname = dt.Rows[0]["forumname"].ToString();
                _title = dt.Rows[0]["title"].ToString();
                _body = dt.Rows[0]["body"].ToString();
                _postby = dt.Rows[0]["postby"].ToString();
                _postdate = Convert.ToDateTime(dt.Rows[0]["postdate"]);
                _approved = Convert.ToBoolean(dt.Rows[0]["approved"]);
                _postid = Convert.ToInt64(dt.Rows[0]["postid"]);
                _parentpostid = Convert.ToInt64(dt.Rows[0]["parentpostid"]);
                _lastpostdate = Convert.ToDateTime(dt.Rows[0]["lastpostdate"]);
            }
        }

        internal ForumPost(DataRow row)
            : this()
        {
            _replies = Convert.ToInt32(row["replies"]);
            _sticky = Convert.ToBoolean(row["sticky"]);
            _locked = Convert.ToBoolean(row["locked"]);
            _siteid = row["siteid"].ToString();
            _forumname = row["forumname"].ToString();
            _title = row["title"].ToString();
            _body = row["body"].ToString();
            _postby = row["postby"].ToString();
            _postdate = Convert.ToDateTime(row["postdate"]);
            _approved = Convert.ToBoolean(row["approved"]);
            _postid = Convert.ToInt64(row["postid"]);
            _parentpostid = Convert.ToInt64(row["parentpostid"]);
            _lastpostdate = Convert.ToDateTime(row["lastpostdate"]);
            _likecount = Convert.ToInt32(row["likecount"]);
        }

        public ForumPost()
        {
            _likecount = 0;
            _lastpostdate = DateTime.MinValue;
            _replies = 0;
            _sticky = false;
            _locked = false;
            _siteid = string.Empty;
            _forumname = string.Empty;
            _title = string.Empty;
            _body = string.Empty;
            _postby = string.Empty;
            _postdate = DateTime.MinValue;
            _approved = false;
            _postid = 0;
            _parentpostid = 0;
        }

        public static ForumPost CreateNew(Forum Forum)
        {
            ForumPost p = new ForumPost();
            p._siteid = Forum.Siteid;
            p._forumname = Forum.ForumName;
            p._approved = (Forum.IsModerated ? false : true);
            p._postdate = DateTime.Now;
            p._lastpostdate = p._postdate;
            return p;
        }

        public static ForumPost CreateNew(Forum Forum, Int64 ParentPostId)
        {
            ForumPost p = new ForumPost();
            p._parentpostid = ParentPostId;
            p._siteid = Forum.Siteid;
            p._forumname = Forum.ForumName;
            p._approved = (Forum.IsModerated ? false : true);
            p._postdate = DateTime.Now;
            p._lastpostdate = p._postdate;
            return p;
        }

        public static ForumPost CreateNew(Forum Forum, ForumPost Parent)
        {
            return CreateNew(Forum, Parent.PostId);
        }

        public void Insert()
        {
            DataConnection dbc = new DataConnection();
            Command cmd = null;

            if (_parentpostid == 0)
            {
                cmd = new Command("BEGIN TRANSACTION;DECLARE @postid bigint;SET @postid = 0;SELECT TOP 1 @postid = postid FROM forumitems WHERE forumname = @forumname AND siteid = @siteid ORDER BY postid DESC;SET @postid = @postid + 1;INSERT INTO forumitems (siteid, forumname, postid, parentpostid, title, body, postby, postdate, approved, locked, sticky, replies, lastpostdate, likecount) VALUES (@siteid, @forumname, @postid, @parentpostid, @title, @body, @postby, @postdate, @approved, @locked, @sticky, @replies, @lastpostdate, @likecount);UPDATE forumheader SET threadcount = threadcount + 1, postcount = postcount + 1, lastpostid = @postid WHERE siteid = @siteid AND forumname = @forumname AND @approved = 1; SELECT @postid AS postid;COMMIT TRANSACTION;");
            }
            else
            {
                cmd = new Command("BEGIN TRANSACTION;DECLARE @postid bigint;SET @postid = 0;SELECT TOP 1 @postid = postid FROM forumitems WHERE forumname = @forumname AND siteid = @siteid ORDER BY postid DESC;SET @postid = @postid + 1;INSERT INTO forumitems (siteid, forumname, postid, parentpostid, title, body, postby, postdate, approved, locked, sticky, replies, lastpostdate, likecount) VALUES (@siteid, @forumname, @postid, @parentpostid, @title, @body, @postby, @postdate, @approved, @locked, @sticky, @replies, @lastpostdate, @likecount);UPDATE forumheader SET postcount = postcount + 1, lastpostid = @postid WHERE siteid = @siteid AND forumname = @forumname AND @approved = 1; UPDATE forumitems SET replies = replies + 1, lastpostdate = @postdate WHERE postid = @parentpostid AND siteid = @siteid AND forumname = @forumname;SELECT @postid AS postid; COMMIT TRANSACTION;");
            }

            cmd.AddParameter("@likecount", _likecount);
            cmd.AddParameter("@lastpostdate", _lastpostdate);
            cmd.AddParameter("@siteid", _siteid);
            cmd.AddParameter("@forumname", _forumname);
            cmd.AddParameter("@parentpostid", _parentpostid);
            cmd.AddParameter("@title", _title);
            cmd.AddParameter("@body", _body);
            cmd.AddParameter("@postby", _postby);
            cmd.AddParameter("@postdate", _postdate);
            cmd.AddParameter("@approved", _approved);
            cmd.AddParameter("@locked", _locked);
            cmd.AddParameter("@sticky", _sticky);
            cmd.AddParameter("@replies", _replies);
            DataTable dt = dbc.FetchDataTable(cmd);
            if (dt.Rows.Count > 0)
            {
                _postid = Convert.ToInt64(dt.Rows[0]["Postid"]);
            }
        }

        public void Update()
        {
            if (_postid == 0) { Insert(); return; }
            DataConnection dbc = new DataConnection();
            Command cmd = new Command("UPDATE forumitems SET parentpostid = @parentpostid, title = @title, body = @body, postby = @postby, postdate = @postdate, approved = @approved, locked = @locked, sticky = @sticky WHERE postid = @postid AND forumname = @forumname AND siteid = @siteid");
            cmd.AddParameter("@postid", _postid);
            cmd.AddParameter("@siteid", _siteid);
            cmd.AddParameter("@forumname", _forumname);
            cmd.AddParameter("@parentpostid", _parentpostid);
            cmd.AddParameter("@title", _title);
            cmd.AddParameter("@body", _body);
            cmd.AddParameter("@postby", _postby);
            cmd.AddParameter("@postdate", _postdate);
            cmd.AddParameter("@approved", _approved);
            cmd.AddParameter("@locked", _locked);
            cmd.AddParameter("@sticky", _sticky);
            dbc.ExecuteCommand(cmd);
        }

        public void Delete()
        {
            DataConnection dbc = new DataConnection();
            Command cmd = new Command("DELETE FROM forumitems WHERE postid = @postid AND forumname = @forumname AND siteid = @siteid;DELETE FROM forumitems WHERE parentpostid = @postid AND forumname = @forumname AND siteid = @siteid");
            cmd.AddParameter("@postid", _postid);
            cmd.AddParameter("@siteid", _siteid);
            cmd.AddParameter("@forumname", _forumname);
            dbc.ExecuteCommand(cmd);
        }

        public void LockThread()
        {
            SetThreadStatus(true);
        }

        public void UnlockThread()
        {
            SetThreadStatus(false);
        }

        public void ApprovePost()
        {
            if (_approved) { return; }
            DataConnection dbc = new DataConnection();
            Command cmd = null;

            if (_parentpostid == 0)
            {
                cmd = new Command("BEGIN TRANSACTION; UPDATE forumitems SET approved = 1 WHERE postid = @postid AND forumname = @forumname AND siteid = @siteid; UPDATE forumheader SET threadcount = threadcount + 1, postcount = postcount + 1, lastpostid = @postid WHERE siteid = @siteid AND forumname = @forumname; COMMIT TRANSACTION");
            }
            else
            {
                cmd = new Command("BEGIN TRANSACTION; UPDATE forumitems SET approved = 1 WHERE postid = @postid AND forumname = @forumname AND siteid = @siteid; UPDATE forumheader SET postcount = postcount + 1, lastpostid = @postid WHERE siteid = @siteid AND forumname = @forumname; COMMIT TRANSACTION");
            }
            cmd.AddParameter("@postid", _postid);
            cmd.AddParameter("@siteid", _siteid);
            cmd.AddParameter("@forumname", _forumname);
            dbc.ExecuteCommand(cmd);
        }

        public void Like()
        {
            DataConnection dbc = new DataConnection();
            Command cmd = null;
            cmd = new Command("UPDATE forumitems SET likecount = likecount + 1 WHERE postid = @postid AND forumname = @forumname AND siteid = @siteid");
            cmd.AddParameter("@postid", _postid);
            cmd.AddParameter("@siteid", _siteid);
            cmd.AddParameter("@forumname", _forumname);
            dbc.ExecuteCommand(cmd);
        }

        public void UnLike()
        {
            DataConnection dbc = new DataConnection();
            Command cmd = null;
            cmd = new Command("UPDATE forumitems SET likecount = likecount - 1 WHERE likecount > 0 AND postid = @postid AND forumname = @forumname AND siteid = @siteid");
            cmd.AddParameter("@postid", _postid);
            cmd.AddParameter("@siteid", _siteid);
            cmd.AddParameter("@forumname", _forumname);
            dbc.ExecuteCommand(cmd);
        }

        public void UnApprovePost()
        {
            if (_approved) { return; }
            DataConnection dbc = new DataConnection();
            Command cmd = null;
            cmd = new Command("UPDATE forumitems SET approved = 0 WHERE postid = @postid AND forumname = @forumname AND siteid = @siteid");
            cmd.AddParameter("@postid", _postid);
            cmd.AddParameter("@siteid", _siteid);
            cmd.AddParameter("@forumname", _forumname);
            dbc.ExecuteCommand(cmd);
        }

        private void SetThreadStatus(bool locked)
        {
            DataConnection dbc = new DataConnection();
            Command cmd = new Command("UPDATE forumitems SET locked = @locked WHERE (postid = @postid OR parentpostid = @postid) AND forumname = @forumname AND siteid = @siteid");
            cmd.AddParameter("@postid", _postid);
            cmd.AddParameter("@siteid", _siteid);
            cmd.AddParameter("@forumname", _forumname);
            cmd.AddParameter("@locked", locked);
            dbc.ExecuteCommand(cmd);
        }
    }
}
